package com.tetris

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.drawscope.DrawScope

// ████
class Block2: Block {
    /**
     * 构造方法。
     */
    constructor() {
        for (j in 0 ..< Const.BLOCK_GRID_COUNT_V) {
            mBlocks[1][j].mUsed = true
        }
    }

    /**
     * 进入预览区域。
     * @param previewWidth  预览区域宽度
     * @param previewHeight 预览区域高度
     * @param drawer        绘图者
     */
    override fun enterPreview(previewWidth: Float, previewHeight: Float, drawer: DrawScope) {
        val x = previewWidth / 2f - Const.GRID_SIZE * 2f
        val y = (previewHeight - Const.GRID_SIZE) / 2f

        for (j in 0 ..< Const.BLOCK_GRID_COUNT_H) {
            drawer.drawRect(mColor, Offset(x + Const.GRID_SIZE * j, y.toFloat()), Size(Const.GRID_SIZE, Const.GRID_SIZE))
            drawEdge(drawer, x + Const.GRID_SIZE * j, y)
        }
    }

    /**
     * 获取底端所在的行数。底端是指方块最下方的有效格。
     */
    override val bottom: Int
        get() {
            if (mShape.value == Shape.ONE) {
                return mRow.intValue + 1
            }
            return mRow.intValue + 3
        }

    /**
     * 对不能下落的处理。
     */
    override fun handleCannotMoveDown() {
        when (mShape.value) {
            Shape.ONE -> {
                for (j in 0 ..< Const.BLOCK_GRID_COUNT_H) {
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + j].mUsed = true
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + j].mColor = mColor
                }
            }
            Shape.TWO -> {
                for (i in 0 ..< Const.BLOCK_GRID_COUNT_V) {
                    Game.sExistentBlocks[mRow.intValue + i][mLine.intValue + 1].mUsed = true
                    Game.sExistentBlocks[mRow.intValue + i][mLine.intValue + 1].mColor = mColor
                }
            }
            else -> {}
        }
    }

    /**
     * 下落。
     * @return 成功则返回 true，否则为 false
     */
    override fun moveDown(): Boolean {
        when (mShape.value) {
            Shape.ONE -> {
                if (mRow.intValue == 18) {
                    this.handleCannotMoveDown()
                    return false
                }
                for (i in 0 ..< Const.BLOCK_GRID_COUNT_H) {
                    if (Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + i].mUsed) {
                        this.handleCannotMoveDown()
                        return false
                    }
                }
            }
            Shape.TWO -> {
                if (mRow.intValue == 16) {
                    this.handleCannotMoveDown()
                    return false
                }
                if (Game.sExistentBlocks[mRow.intValue + 4][mLine.intValue + 1].mUsed) {
                    this.handleCannotMoveDown()
                    return false
                }
            }
            else -> {}
        }

        return super.moveDown()
    }

    /**
     * 左移。
     */
    override fun moveLeft() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mLine.intValue == 0) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue - 1].mUsed) {
                    return
                }
            }
            Shape.TWO -> {
                if (mLine.intValue == -1) {
                    return
                }
                for (i in 0 ..< Const.BLOCK_GRID_COUNT_V) {
                    if (Game.sExistentBlocks[mRow.intValue + i][mLine.intValue].mUsed) {
                        return
                    }
                }
            }
            else -> {}
        }

        super.moveLeft()
    }

    /**
     * 右移。
     */
    override fun moveRight() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mLine.intValue == 6) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 4].mUsed) {
                    return
                }
            }
            Shape.TWO -> {
                if (mLine.intValue == 8) {
                    return
                }
                for (i in 0 ..< Const.BLOCK_GRID_COUNT_V) {
                    if (Game.sExistentBlocks[mRow.intValue + i][mLine.intValue + 2].mUsed) {
                        return
                    }
                }
            }
            else -> {}
        }

        super.moveRight()
    }

    /**
     * 获取顶端所在的行数。顶端是指方块最上方的有效格。
     */
    override val top: Int
        get() {
            if (mShape.value == Shape.ONE) {
                return mRow.intValue + 1
            }
            return mRow.intValue
        }

    /**
     * 变形。
     */
    override fun transform() {
        when (mShape.value) {
            Shape.ONE -> {
                if (mRow.intValue == -1 || mRow.intValue >= 17) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue][mLine.intValue + 1].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 2][mLine.intValue + 1].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 3][mLine.intValue + 1].mUsed) {
                    return
                }
                mBlocks[1][3].mUsed = false
                mBlocks[1][2].mUsed = false
                mBlocks[1][0].mUsed = false
                mBlocks[3][1].mUsed = true
                mBlocks[2][1].mUsed = true
                mBlocks[0][1].mUsed = true
                mShape.value = Shape.TWO
            }
            Shape.TWO -> {
                if (mLine.intValue == -1 || mLine.intValue >= 7) {
                    return
                }
                if (Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 2].mUsed ||
                    Game.sExistentBlocks[mRow.intValue + 1][mLine.intValue + 3].mUsed) {
                    return
                }
                mBlocks[1][3].mUsed = true
                mBlocks[1][2].mUsed = true
                mBlocks[1][0].mUsed = true
                mBlocks[3][1].mUsed = false
                mBlocks[2][1].mUsed = false
                mBlocks[0][1].mUsed = false
                mShape.value = Shape.ONE
            }
            else -> {}
        }
    }
}
